<template>
    <view class="container">
        <!-- 全屏摄像头预览 -->
        <view class="camera-preview">
            <!-- 小程序相机预览组件 -->
            <!-- #ifndef H5 -->
            <camera
                class="camera"
                device-position="front"
                flash="auto"
                output-dimension="360P"
                frame-size="small"
                resolution="low"
                @error="cameraError"
            ></camera>
            <!-- #endif -->

            <!-- H5视频预览 -->
            <!-- #ifdef H5 -->
            <view
                class="h5-video-container"
                :style="{ width: '100%', height: '100%', position: 'absolute', top: 0, left: 0 }"
            >
                <view id="h5-video-wrapper" style="width: 100%; height: 100%">
                    <!-- 这里会通过原生JS创建video元素 -->
                </view>
            </view>
            <view id="h5-canvas-wrapper" style="position: absolute; top: -9999px; left: -9999px">
                <!-- canvas会通过原生JS创建 -->
            </view>
            <!-- #endif -->
        </view>

        <!-- 小程序环境：使用 cover-view 显示消息提示 -->
        <!-- #ifndef H5 -->
        <cover-view v-if="messages.length > 0" class="cover-desc-box">
            <cover-view class="cover-label-desc" v-for="(item, index) in messages" :key="index">{{
                item
            }}</cover-view>
        </cover-view>

        <!-- 训练状态指示器 - 使用 cover-view -->
        <cover-view v-if="isTraining" class="cover-live-indicator">
            <cover-view class="cover-live-dot"></cover-view>
            <cover-view class="cover-live-text">训练中</cover-view>
        </cover-view>
        <!-- #endif -->

        <!-- H5环境：使用普通 view 显示消息提示 -->
        <!-- #ifdef H5 -->
        <view v-if="messages.length > 0" class="cover-desc-box">
            <view class="cover-label-desc" v-for="(item, index) in messages" :key="index">{{
                item
            }}</view>
        </view>

        <!-- H5 训练状态指示器 -->
        <view v-if="isTraining" class="cover-live-indicator">
            <view class="cover-live-dot"></view>
            <text class="cover-live-text">训练中</text>
        </view>
        <!-- #endif -->

        <!-- 小程序环境：倒计时显示 - 使用 cover-view -->
        <!-- #ifndef H5 -->
        <cover-view v-if="isCountingDown" class="cover-countdown-overlay">
            <cover-view class="cover-countdown-circle">
                <cover-view class="cover-countdown-number">{{ countdownTime }}</cover-view>
            </cover-view>
            <cover-view class="cover-countdown-text">即将开始</cover-view>
        </cover-view>
        <!-- #endif -->

        <!-- H5环境：倒计时显示 -->
        <!-- #ifdef H5 -->
        <view v-if="isCountingDown" class="cover-countdown-overlay">
            <view class="cover-countdown-circle">
                <text class="cover-countdown-number">{{ countdownTime }}</text>
            </view>
            <text class="cover-countdown-text">即将开始</text>
        </view>
        <!-- #endif -->

        <!-- 小程序环境：使用 cover-view 实现弹窗 - 可以覆盖在 camera 上 -->
        <!-- #ifndef H5 -->
        <cover-view
            v-if="hasShownPopup && !isTraining && !isCountingDown"
            class="cover-popup-overlay"
        >
            <cover-view class="cover-popup">
                <cover-view class="cover-popup-title">开始训练</cover-view>
                <cover-view class="cover-popup-subtitle">点击下方按钮开始康复训练</cover-view>
                <cover-view class="cover-start-btn" @tap="startCountdown">
                    <cover-view class="btn-text">开始训练</cover-view>
                </cover-view>
            </cover-view>
        </cover-view>

        <!-- 训练结束弹窗 - 使用 cover-view -->
        <cover-view v-if="showFinishPopup" class="cover-popup-overlay">
            <cover-view class="cover-popup cover-finish-popup">
                <cover-view class="cover-popup-icon cover-finish-icon">
                    <cover-view class="icon-text">✓</cover-view>
                </cover-view>
                <cover-view class="cover-popup-title">训练完成</cover-view>
                <cover-view class="cover-popup-subtitle">您已完成本次康复训练</cover-view>
                <cover-view class="cover-finish-btn" @tap="goBack">
                    <cover-view class="btn-text">确定</cover-view>
                </cover-view>
            </cover-view>
        </cover-view>
        <!-- #endif -->

        <!-- H5环境：使用普通 view 实现弹窗 -->
        <!-- #ifdef H5 -->
        <view
            v-if="hasShownPopup && !isTraining && !isCountingDown"
            class="cover-popup-overlay"
            @click.stop
        >
            <view class="cover-popup">
                <view class="cover-popup-title">开始训练</view>
                <view class="cover-popup-subtitle">点击下方按钮开始康复训练</view>
                <view class="cover-start-btn" @click="startCountdown">
                    <text class="btn-text">开始训练</text>
                </view>
            </view>
        </view>

        <!-- H5 训练结束弹窗 -->
        <view v-if="showFinishPopup" class="cover-popup-overlay" @click.stop>
            <view class="cover-popup">
                <view class="cover-popup-icon cover-finish-icon">
                    <text class="icon-text">✓</text>
                </view>
                <view class="cover-popup-title">训练完成</view>
                <view class="cover-popup-subtitle">您已完成本次康复训练</view>
                <view class="cover-finish-btn" @click="goBack">
                    <text class="btn-text">确定</text>
                </view>
            </view>
        </view>
        <!-- #endif -->
    </view>
</template>

<script>
import socket from '@/common/socket';
import { saveTrainInfo } from '@/api/modules/common.js';
import useUserStore from '@/stores/modules/user';

export default {
    data() {
        return {
            isTraining: false,
            isCountingDown: false,
            countdownTime: 3,
            countdownTimer: null,
            cameraContext: null,
            cameraFrameListener: null,
            hasShownPopup: false,
            showFinishPopup: false,
            isPageReady: false,
            params: { child_id: '' },
            // ws: 'wss://trainws.logs.fund/',
            ws: 'wss://trainws.logs.fund/',
            count: 0,
            messages: [],
            // H5专用变量
            h5VideoStream: null,
            h5FrameTimer: null,
            h5VideoElement: null,
            h5CanvasElement: null
        };
    },
    onLoad(data) {
        uni.$on('complete', () => {
            this.completeTask();
        });
        uni.$on('FACE_STATE', data => {
            this.messages = data.data.messages;
        });

        if (data && data.category_ap) {
            this.ws += data.category_ap;
            this.params.child_id = data.child_id;
        }
        // 缓存token
        useUserStore().modifyUserToken(data.token);
        this.startSocket();
    },
    onReady() {
        this.isPageReady = true;

        // #ifdef H5
        // H5环境：直接初始化视频流
        this.initH5VideoStream();
        // #endif

        // #ifndef H5
        // 小程序环境：显示开始训练弹窗
        setTimeout(() => {
            this.showStartPopup();
        }, 500);
        // #endif
    },
    onBackPress() {
        // 如果弹窗已显示或正在训练，阻止返回
        if (this.hasShownPopup || this.isTraining || this.isCountingDown) {
            return true;
        }
        return false;
    },
    onUnload() {
        this.clearTimers();
        socket.closeSocket();

        // #ifdef H5
        // 清理H5视频流
        if (this.h5VideoStream) {
            this.h5VideoStream.getTracks().forEach(track => track.stop());
            this.h5VideoStream = null;
        }
        // 清理video元素
        if (this.h5VideoElement) {
            this.h5VideoElement.srcObject = null;
            this.h5VideoElement = null;
        }
        this.h5CanvasElement = null;
        // #endif
    },
    methods: {
        // 返回上一页
        goBack() {
            console.log('[Training] 返回上一页');
            this.showFinishPopup = false;
            uni.navigateBack({
                delta: 1
            });
        },

        // 清理定时器
        clearTimers() {
            if (this.countdownTimer) {
                clearInterval(this.countdownTimer);
                this.countdownTimer = null;
            }

            // #ifdef H5
            // 清理H5帧捕获定时器
            if (this.h5FrameTimer) {
                clearInterval(this.h5FrameTimer);
                this.h5FrameTimer = null;
            }
            // #endif
        },

        // 开始倒计时
        startCountdown() {
            console.log('开始倒计时');
            // 关闭开始训练弹窗
            this.hasShownPopup = false;
            // 显示倒计时
            this.isCountingDown = true;
            this.countdownTime = 3;

            this.countdownTimer = setInterval(() => {
                this.countdownTime--;
                console.log('倒计时:', this.countdownTime);

                if (this.countdownTime <= 0) {
                    this.clearTimers();
                    this.startTraining();
                }
            }, 1000);
        },

        // 开始链接ws
        startSocket() {
            console.log('开始链接');
            socket.initSocket(this.ws);
        },

        // 开始训练
        startTraining() {
            this.isCountingDown = false;
            this.isTraining = true;

            // 建连后先发送 train_id 文本（控制指令）
            if (this.params.child_id) {
                socket.send('train_id: ' + this.params.child_id);
            }

            // #ifdef H5
            // H5环境：使用Canvas捕获视频帧
            this.startH5FrameCapture();
            // #endif

            // #ifndef H5
            // 小程序环境：使用相机帧监听
            if (!this.cameraContext) {
                this.cameraContext = uni.createCameraContext();
            }

            // 监听相机帧数据（节流发送）
            const listener = this.cameraContext.onCameraFrame(frame => {
                if (!this.isTraining) return;

                socket.send(JSON.stringify({ width: frame.width, height: frame.height }));

                // 二进制直发（ArrayBuffer）
                if (frame && frame.data) {
                    this.count++;
                    if (this.count % 2 == 0) {
                        socket.send(frame.data);
                        console.log('发送二进制');
                    }
                }
            });

            // 启动监听
            listener.start();

            // 保存监听器引用
            this.cameraFrameListener = listener;

            // #endif
        },

        // H5环境：开始帧捕获
        startH5FrameCapture() {
            if (!this.h5VideoElement || !this.h5CanvasElement) {
                console.error('Video或Canvas元素未找到');
                // 尝试获取元素
                this.h5VideoElement = document.getElementById('h5-native-video');
                this.h5CanvasElement = document.getElementById('h5-native-canvas');

                if (!this.h5VideoElement || !this.h5CanvasElement) {
                    console.error('无法获取H5 video或canvas元素');
                    return;
                }
            }

            const ctx = this.h5CanvasElement.getContext('2d');
            const width = 640;
            const height = 480;

            console.log('开始H5帧捕获，视频元素状态:', {
                readyState: this.h5VideoElement.readyState,
                videoWidth: this.h5VideoElement.videoWidth,
                videoHeight: this.h5VideoElement.videoHeight
            });

            // 每隔一定时间捕获一帧（类似小程序的节流）
            this.h5FrameTimer = setInterval(() => {
                if (!this.isTraining) return;

                try {
                    // 绘制当前视频帧到canvas（需要镜像翻转回来）
                    ctx.save();
                    ctx.scale(-1, 1);
                    ctx.drawImage(this.h5VideoElement, -width, 0, width, height);
                    ctx.restore();

                    // 节流发送（每2帧发送一次）
                    this.count++;
                    if (this.count % 2 === 0) {
                        // 获取原始RGBA像素数据
                        const imageData = ctx.getImageData(0, 0, width, height);

                        // 发送尺寸信息
                        socket.send(JSON.stringify({ width, height }));

                        // 发送原始像素数据的ArrayBuffer（RGBA格式，每像素4字节）
                        socket.send(imageData.data.buffer);
                    }
                } catch (error) {
                    console.error('H5帧捕获错误:', error);
                }
            }, 100); // 每100ms捕获一帧，约10fps
        },

        async completeTask() {
            try {
                console.log('训练结束');
                await saveTrainInfo(this.params);
                uni.removeStorageSync('play_data');
                this.finishTraining();
            } catch (error) {
                console.log(error);
                this.completeTask();
            }
        },

        // 结束训练
        finishTraining() {
            // 停止训练状态
            this.isTraining = false;

            socket.closeSocket();

            // #ifdef H5
            // 停止H5帧捕获定时器
            if (this.h5FrameTimer) {
                clearInterval(this.h5FrameTimer);
                this.h5FrameTimer = null;
            }
            // #endif

            // #ifndef H5
            // 停止相机帧监听（小程序环境）
            if (this.cameraFrameListener) {
                this.cameraFrameListener.stop();
                this.cameraFrameListener = null;
            }
            // #endif

            // 显示训练结束弹窗
            this.showFinishPopup = true;
        },

        // 相机错误处理
        cameraError(e) {
            console.error('相机错误:', e.detail);
        },

        // H5环境：初始化视频流
        async initH5VideoStream() {
            // #ifdef H5
            try {
                // 获取前置摄像头（facingMode: user 表示前置）
                const stream = await navigator.mediaDevices.getUserMedia({
                    video: {
                        facingMode: 'user',
                        width: { ideal: 640 },
                        height: { ideal: 480 }
                    }
                });

                this.h5VideoStream = stream;

                // 创建原生video元素
                this.$nextTick(() => {
                    this.createH5VideoElement(stream);
                });

                // 显示开始训练弹窗
                setTimeout(() => {
                    this.showStartPopup();
                }, 500);
            } catch (error) {
                console.error('H5摄像头初始化失败:', error);
                uni.showToast({
                    title: '无法访问摄像头',
                    icon: 'none'
                });
            }
            // #endif
        },

        // 创建H5 video和canvas元素
        createH5VideoElement(stream) {
            // 创建video元素
            const videoWrapper = document.getElementById('h5-video-wrapper');
            if (!videoWrapper) {
                console.error('h5-video-wrapper未找到');
                return;
            }

            const video = document.createElement('video');
            video.id = 'h5-native-video';
            video.autoplay = true;
            video.playsInline = true;
            video.muted = true;
            video.style.width = '100%';
            video.style.height = '100%';
            video.style.objectFit = 'cover';
            video.style.transform = 'scaleX(-1)'; // 镜像翻转

            // 绑定视频流
            video.srcObject = stream;

            // 确保视频开始播放
            video.play().catch(err => {
                console.error('视频播放失败:', err);
            });

            videoWrapper.appendChild(video);
            this.h5VideoElement = video;

            // 创建canvas元素
            const canvasWrapper = document.getElementById('h5-canvas-wrapper');
            if (canvasWrapper) {
                const canvas = document.createElement('canvas');
                canvas.id = 'h5-native-canvas';
                canvas.width = 640;
                canvas.height = 480;
                canvasWrapper.appendChild(canvas);
                this.h5CanvasElement = canvas;
            }

            console.log('H5 video和canvas元素创建成功');
        },

        // 初始化相机上下文
        initCameraContext() {
            // #ifndef H5
            // 小程序环境：创建相机上下文
            if (!this.cameraContext) {
                this.cameraContext = uni.createCameraContext();
            }
            // #endif

            // #ifdef H5
            // H5环境：不需要创建相机上下文，直接使用 HTML5 video 元素
            console.log('H5环境，使用浏览器原生摄像头API');
            // #endif
        },

        // 显示开始训练弹窗
        showStartPopup() {
            if (this.hasShownPopup) {
                return;
            }
            this.hasShownPopup = true;
        }
    }
};
</script>

<style lang="scss">
.container {
    width: 100vw;
    height: 100vh;
    position: relative;
    overflow: hidden;
}

.camera-preview {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    position: relative;
}

.camera {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

// H5视频容器样式
.h5-video-container {
    width: 100%;
    height: 100%;
}

// cover-view 弹窗样式（H5和小程序共用）
.cover-popup-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.7);
    z-index: 99999;
    display: flex;
    justify-content: center;
    align-items: center;
}

.cover-popup {
    width: 600rpx;
    max-width: 80%;
    background-color: #ffffff;
    border-radius: 30rpx;
    padding: 60rpx 40rpx;
    box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.3);
    display: flex;
    flex-direction: column;
    align-items: center;
}

.cover-popup-title {
    font-size: 40rpx;
    font-weight: bold;
    color: #333333;
    text-align: center;
    margin-bottom: 20rpx;
}

.cover-popup-subtitle {
    font-size: 28rpx;
    color: #666666;
    text-align: center;
    margin-bottom: 50rpx;
}

.cover-start-btn {
    width: 100%;
    max-width: 520rpx;
    height: 88rpx;
    background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
    border-radius: 44rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    box-shadow: 0 8rpx 25rpx rgba(239, 68, 68, 0.3);

    &:active {
        transform: scale(0.95);
    }

    .btn-text {
        font-size: 32rpx;
        font-weight: bold;
        color: #ffffff;
    }
}

// 训练结束弹窗特定样式
.cover-popup-icon {
    width: 120rpx;
    height: 120rpx;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 30rpx;

    &.cover-finish-icon {
        background: linear-gradient(135deg, #10b981 0%, #059669 100%);
        box-shadow: 0 10rpx 30rpx rgba(16, 185, 129, 0.3);
    }

    .icon-text {
        font-size: 60rpx;
        color: #ffffff;
        font-weight: bold;
    }
}

.cover-finish-btn {
    width: 100%;
    max-width: 520rpx;
    height: 88rpx;
    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
    border-radius: 44rpx;
    display: flex;
    justify-content: center;
    align-items: center;
    box-shadow: 0 8rpx 25rpx rgba(16, 185, 129, 0.3);

    &:active {
        transform: scale(0.95);
    }

    .btn-text {
        font-size: 32rpx;
        font-weight: bold;
        color: #ffffff;
    }
}

// cover-view 版本的消息提示框（H5和小程序共用）
.cover-desc-box {
    position: fixed;
    right: 30rpx;
    bottom: 100rpx;
    width: 375rpx;
    z-index: 9999;
}

.cover-label-desc {
    color: #ffffff;
    font-size: 24rpx;
    line-height: 50rpx;
    background-color: rgba(0, 0, 0, 0.5);
    padding: 10rpx 20rpx;
    border-radius: 10rpx;
    margin-bottom: 10rpx;
}

// cover-view 版本的训练状态指示器
.cover-live-indicator {
    position: fixed;
    top: 40rpx;
    left: 40rpx;
    background-color: rgba(239, 68, 68, 0.9);
    border-radius: 30rpx;
    padding: 12rpx 20rpx;
    display: flex;
    flex-direction: row;
    align-items: center;
    z-index: 10;
}

.cover-live-dot {
    width: 16rpx;
    height: 16rpx;
    background-color: #ffffff;
    border-radius: 50%;
    margin-right: 10rpx;
}

.cover-live-text {
    color: #ffffff;
    font-size: 24rpx;
    font-weight: bold;
}

// cover-view 版本的倒计时（H5和小程序共用）
.cover-countdown-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.7);
    z-index: 20;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.cover-countdown-circle {
    width: 200rpx;
    height: 200rpx;
    background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    box-shadow: 0 15rpx 35rpx rgba(245, 158, 11, 0.4);
    animation: countdownPulse 1s infinite;
    margin-bottom: 40rpx;
}

.cover-countdown-number {
    font-size: 80rpx;
    font-weight: bold;
    color: #ffffff;
    text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
}

.cover-countdown-text {
    color: #ffffff;
    font-size: 32rpx;
    font-weight: bold;
}

.live-indicator {
    position: absolute;
    top: 60rpx;
    left: 40rpx;
    background: rgba(239, 68, 68, 0.9);
    border-radius: 30rpx;
    padding: 12rpx 20rpx;
    display: flex;
    align-items: center;
    gap: 10rpx;
    backdrop-filter: blur(10rpx);
    z-index: 10;

    .live-dot {
        width: 16rpx;
        height: 16rpx;
        background: #fff;
        border-radius: 50%;
        animation: liveBlink 1s infinite;
    }

    .live-text {
        color: #fff;
        font-size: 24rpx;
        font-weight: bold;
    }
}

@keyframes liveBlink {
    0%,
    100% {
        opacity: 1;
    }
    50% {
        opacity: 0.3;
    }
}

.countdown-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.7);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    z-index: 20;
}

.countdown-circle {
    width: 200rpx;
    height: 200rpx;
    background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 40rpx;
    box-shadow: 0 15rpx 35rpx rgba(245, 158, 11, 0.4);
    animation: countdownPulse 1s infinite;

    .countdown-number {
        font-size: 80rpx;
        font-weight: bold;
        color: #fff;
        text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
    }
}

.countdown-text {
    color: #fff;
    font-size: 32rpx;
    font-weight: bold;
}

@keyframes countdownPulse {
    0%,
    100% {
        transform: scale(1);
    }
    50% {
        transform: scale(1.1);
    }
}

.start-popup {
    background-color: #fff;
    border-radius: 30rpx;
    padding: 60rpx 40rpx;
    margin: 40rpx;
    box-shadow: 0 20rpx 40rpx rgba(0, 0, 0, 0.15);
    width: 80vw;
}

.popup-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.popup-icon {
    width: 120rpx;
    height: 120rpx;
    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 30rpx;
    box-shadow: 0 10rpx 30rpx rgba(16, 185, 129, 0.3);
}

.popup-title {
    font-size: 36rpx;
    font-weight: bold;
    color: #333;
    margin-bottom: 20rpx;
}

.popup-subtitle {
    font-size: 28rpx;
    color: #666;
    line-height: 1.5;
    margin-bottom: 40rpx;
}

.start-btn {
    width: 100%;
    height: 80rpx;
    background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
    color: #fff;
    border: none;
    border-radius: 40rpx;
    font-size: 30rpx;
    font-weight: bold;
    box-shadow: 0 8rpx 25rpx rgba(239, 68, 68, 0.3);
    transition: all 0.3s ease;

    &:active {
        transform: scale(0.95);
    }
}

.finish-popup {
    background-color: #fff;
    border-radius: 30rpx;
    padding: 60rpx 40rpx;
    margin: 40rpx;
    box-shadow: 0 20rpx 40rpx rgba(0, 0, 0, 0.15);
    width: 80vw;
}

.finish-icon {
    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
}

.finish-btn {
    width: 100%;
    height: 80rpx;
    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
    color: #fff;
    border: none;
    border-radius: 40rpx;
    font-size: 30rpx;
    font-weight: bold;
    box-shadow: 0 8rpx 25rpx rgba(16, 185, 129, 0.3);
    transition: all 0.3s ease;

    &:active {
        transform: scale(0.95);
    }
}
</style>
